﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoxelBlock.VoxelInput;
using VoxelBlock;
public static class SaveRiovox
{
    public static void Save(string path)
    {
        ProxyOperation[] allOverProxyOperation;
        RioVoxelData riovox = GetRiovox(out allOverProxyOperation);

        RioVoxelDataIO.Save(path, riovox);
    }

    public static RioVoxelData GetRiovox(out ProxyOperation[] allOverProxyOperation)
    {
        Dictionary<VoxelUnitData, ProxyOperation> allProxyOperation = new Dictionary<VoxelUnitData, ProxyOperation>();
       

        RioVoxelData riovox = new RioVoxelData(true);

        Color32[] colors = VoxelEditorMastermind.instance.EditingTex.GetPixels32();



        VoxelHeadData[] headDatas = new VoxelHeadData[2];
        headDatas[0] = new VoxelHeadData();
        headDatas[0].operationData = "";
        headDatas[0].operationType = "encryption";
        headDatas[0].isOpen = false;

        headDatas[1] = new VoxelHeadData();
        headDatas[1].operationData = "";
        headDatas[1].operationType = "compress";
        headDatas[1].isOpen = false;
        //List<int> boneIndexs = new List<int>();
        //List<byte[]> allByteData = new List<byte[]>();
        //List<Vector3> allPosition = new List<Vector3>();


        Transform skeletonPoint = GameObject.FindObjectOfType<MainSkeletonComponent>().transform;
        Dictionary<int, int> dicInstanceToIndex;
        GetAllTransform(skeletonPoint, out dicInstanceToIndex);
        Dictionary<int, VoxelBoneTransform> dicVoxelBoneTranform = new Dictionary<int, VoxelBoneTransform>();
        Dictionary<int, VoxelUnitData> dicVoxelUnitData = new Dictionary<int, VoxelUnitData>();
        List<VoxelUnitData> listVoxelUnitData = new List<VoxelUnitData>();

        UnitMeshPointComponent[] allUnitMeshPointComponent = GameObject.FindObjectsOfType<UnitMeshPointComponent>();

        foreach (var item in allUnitMeshPointComponent)
        {
            if (item.m_boneTarget)// && !item.m_boneTarget.name.Equals("Bone Parent")
            {
                VoxelBoneTransform myTranform = new VoxelBoneTransform(item.m_boneTarget.name, dicInstanceToIndex[item.m_boneTarget.GetInstanceID()]);
                dicVoxelBoneTranform[item.m_boneTarget.GetInstanceID()] = myTranform;

                VoxelUnitData voxelUnitData = new VoxelUnitData();
                dicVoxelUnitData[item.m_boneTarget.GetInstanceID()] = voxelUnitData;

                DrawVoxel3DCoreComponent drawComponent = item.GetComponent<DrawVoxel3DCoreComponent>();

                VoxelBlock.VoxelInput.VoxelInputInfo itemVoxelInputInfo
                    = VoxelBlock.VoxelBlock3D.OperateCreate3D.GetFileVoxelData(drawComponent.mainDrawVoxel3DCore);

                Vector3 position2 = new Vector3(itemVoxelInputInfo.minX, itemVoxelInputInfo.minY, itemVoxelInputInfo.minZ);
                Vector3 zeroPosition = item.GetComponent<TransformUnitComponent>().zeroPosition;
                //Debug.Log("min " + position2);
                //Debug.Log("zero " + zeroPosition);
                //Debug.Log("position " + item.transform.position);
                //Debug.Log("over " + -(position2 + item.transform.position - item.GetComponent<TransformUnitComponent>().zeroPosition));
                //Debug.Log("over2 " + (item.GetComponent<TransformUnitComponent>().zeroPosition - item.transform.position - position2));
                voxelUnitData.name = item.name;
                voxelUnitData.min = position2;
                voxelUnitData.zero = zeroPosition;
                voxelUnitData.world = item.transform.position;



                myTranform.localPosition = item.m_boneTarget.localPosition;
                myTranform.pivot = (zeroPosition - item.transform.position) - position2;
                myTranform.localEulerAngles = new Vector3(0, 0, 0);
                myTranform.localScale = new Vector3(1, 1, 1);

                voxelUnitData.voxelData = (VoxelBlock.VoxelInput.VoxelInput.SetVoxelDataOnlyVoxel(itemVoxelInputInfo));
                voxelUnitData.size = (new Vector3Int(itemVoxelInputInfo.SizeX, itemVoxelInputInfo.SizeY, itemVoxelInputInfo.SizeZ));

                allProxyOperation[voxelUnitData] = VoxelEditorMastermind.instance.GetDrawVoxel3DCoreValue(drawComponent.mainDrawVoxel3DCore).proxy;
            }
            else
            {
                DrawVoxel3DCoreComponent drawComponent = item.GetComponent<DrawVoxel3DCoreComponent>();
                VoxelUnitData voxelUnitData = new VoxelUnitData();
                VoxelBlock.VoxelInput.VoxelInputInfo itemVoxelInputInfo
                    = VoxelBlock.VoxelBlock3D.OperateCreate3D.GetFileVoxelData(drawComponent.mainDrawVoxel3DCore);
                Vector3 position2 = new Vector3(itemVoxelInputInfo.minX, itemVoxelInputInfo.minY, itemVoxelInputInfo.minZ);
                Vector3 zeroPosition = item.GetComponent<TransformUnitComponent>().zeroPosition;
                voxelUnitData.name = item.name;
                voxelUnitData.min = position2;
                voxelUnitData.zero = zeroPosition;
                voxelUnitData.world = item.transform.position;
                voxelUnitData.voxelData = (VoxelBlock.VoxelInput.VoxelInput.SetVoxelDataOnlyVoxel(itemVoxelInputInfo));
                voxelUnitData.size = (new Vector3Int(itemVoxelInputInfo.SizeX, itemVoxelInputInfo.SizeY, itemVoxelInputInfo.SizeZ));

                Debug.Log(voxelUnitData.voxelData.Length);
                Debug.Log(voxelUnitData.size);

                listVoxelUnitData.Add(voxelUnitData);

                allProxyOperation[voxelUnitData] = VoxelEditorMastermind.instance.GetDrawVoxel3DCoreValue(drawComponent.mainDrawVoxel3DCore).proxy;
            }
        }



        VoxelUnitData[] allVoxel = new VoxelUnitData[dicVoxelBoneTranform.Count + listVoxelUnitData.Count];
        allOverProxyOperation = new ProxyOperation[allVoxel.Length];
        //Vector3Int[] allVoxelSize = new Vector3Int[dicVoxelBoneTranform.Count];

        VoxelBoneTransform[] tranforms = new VoxelBoneTransform[dicVoxelBoneTranform.Count];
        foreach (var item in allUnitMeshPointComponent)
        {
            if (item.m_boneTarget)
            {
                VoxelBoneTransform myTranform = dicVoxelBoneTranform[item.m_boneTarget.GetInstanceID()];
                if (item.m_boneTarget.parent != null)
                {
                    if (dicVoxelBoneTranform.ContainsKey(item.m_boneTarget.parent.GetInstanceID()))
                    {
                        myTranform.parent = dicVoxelBoneTranform[item.m_boneTarget.parent.GetInstanceID()];
                        myTranform.parentIndex = dicInstanceToIndex[item.m_boneTarget.parent.GetInstanceID()];
                        //myTranform.layer = myTranform.parent.layer + 1;
                    }
                }
                int index = dicInstanceToIndex[item.m_boneTarget.GetInstanceID()];
                tranforms[index] = myTranform;
                allVoxel[index] = dicVoxelUnitData[item.m_boneTarget.GetInstanceID()];
                allOverProxyOperation[index] = allProxyOperation[allVoxel[index]];
            }
        }

        for (int i = dicVoxelBoneTranform.Count; i < allVoxel.Length; i++)
        {
            allVoxel[i] = listVoxelUnitData[i - dicVoxelBoneTranform.Count];
            allOverProxyOperation[i] = allProxyOperation[allVoxel[i]];
        }

        for (int i = 0; i < tranforms.Length; i++)
        {
            if (tranforms[i].parent != null)
            {
                tranforms[i].layer = tranforms[i].parent.layer + 1;
            }
        }


        riovox.allVoxel = allVoxel;
        riovox.transforms = tranforms;
        riovox.colors = colors;
        riovox.headDatas = headDatas;


        //riovox = RioVoxelDataIO.Open(@"F:\Voxel测试程序研究室\新Voxel文件读取器\test.riovox");

        return riovox;
    }

    public static void GetAllTransform(Transform mainTransform, out Dictionary<int, int> dicInstanceToIndex)
    {
        dicInstanceToIndex = new Dictionary<int, int>();
        //dicInstanceToIndex[mainTransform.GetInstanceID()] = dicInstanceToIndex.Count;

        foreach (Transform item in mainTransform)
        {
            if (!item.name.Equals("Bone"))
            {
                dicInstanceToIndex[item.GetInstanceID()] = dicInstanceToIndex.Count;
                GetAllTransform(dicInstanceToIndex, item);
            }
        }
    }

    public static void GetAllTransform( Dictionary<int, int> dicInstanceToIndex, Transform mainTransform)
    {
        foreach (Transform item in mainTransform)
        {
            if (!item.name.Equals("Bone"))
            {
                dicInstanceToIndex[item.GetInstanceID()] = dicInstanceToIndex.Count;
                if (item.childCount > 0)
                {
                    GetAllTransform(dicInstanceToIndex, item);
                }
            }
        }
    }



}
